<!--
 * @Description: 
 * @Version: 0.1
 * @Autor: Civet
 * @Date: 2019-08-02 16:04:58
 * @LastEditors: Civet
 * @LastEditTime: 2019-09-09 10:18:01
 -->
<template>
  <div class="my-tabs" ref="myTabs">
    <div class="iconfont icon-jiantouleft-copy prev" @click="prev" v-show="getIsOverFlowTabs"></div>
    <div class="out-my-tabs" ref="outMyTabs">
      <div ref="scrollTabs" class="tab-box">
        <ul class="tabs">
          <li
            v-for="(item,index) in tabs"
            :key="index"
            :class="item.path === curPath?'active':''"
            @click.stop="tabClick(item,index)"
            @contextmenu="contextmenu($event,item,index)"
          >
            {{item.title}}
            <i class="del iconfont icon-shanchu" @click.stop="delClick(item,index)"></i>
          </li>
        </ul>
      </div>
    </div>
    <div class="iconfont icon-jiantouright-copy next" @click="next" v-show="getIsOverFlowTabs"></div>
    <div v-if="isShowPromptBox" class="prompt-box">
      <div class="mask" @click="isShowPromptBox = false;" @contextmenu="contextmenuClose"></div>
      <ul class="prompt" :style="promptStyle" @contextmenu="contextmenuClose">
        <li v-for="(item,index) in promptData" :key="item.id" @click="promptClick(index,item)">{{item.title}}</li>
      </ul>
    </div>
  </div>
</template>
<script type="text/ecmascript-6">
  import {mapActions, mapGetters} from 'Vuex';
  export default {
    name: 'MyTabs',
    components: {},
    props: {},
    data() {
      return {
        isShowPromptBox: false, // 是否显示右键弹窗
        promptStyle: {// 右键弹窗的样式--位置
          left: 0,
          top: 0
        },
        promptData: [
          {title: '关闭当前', id: 0},
          {title: '关闭其他', id: 1},
          {title: '关闭全部', id: 2}
        ],
        curPath: '', // 当前路径
        configMap: {}, // 侧边栏的映射表
        tabs: [
          // {
          //   title: '欢迎页面',
          //   path: '/frame/HelloWorld'
          // }
        ], // tab栏目的菜单
        fristPath: '/frame',
        prevIndex: 0,
      };
    },
    methods: {
      ...mapActions(['addAddkeepLiveInclude', 'delAddkeepLiveInclude', 'resetAddKeepLiveInclude', 'setOverFlowTabs']),
      /**
       * tab项的点击事件
       * @param {Object} item
       * @param {Number} index
       */
      tabClick(item, index) {
        this.curPath = item.path;
        this.$router.push({path: this.curPath});
      },
      /**
       * tab项的点击删除按钮事件
       * @param {Object} item
       * @param {Number} index
       */
      delClick(item, index) {
        // 清除tab
        this.tabs.splice(index, 1);

        this.makeMove();

        // 清除缓存
        this.delAddkeepLiveInclude(index);
        let tabs = this.tabs;
        let len = tabs.length;
        // 如果删除的项是选中的，那么默认调转到最后一项
        if (item.path === this.curPath) {
          let path = '';
          if (len === 0) {
            this.curPath = '';
            path = this.fristPath;
          } else {
            path = tabs[len - 1].path;
            this.curPath = path;
          }
          this.$router.push({path});
        }
      },
      /**
       * 根据path查看tabs是否存在
       * @param {String} path 路径
       * @returns {*} 配置项  如果为null代表没有该配置项
       */
      hasTbasByPath(path) {
        let tabs = this.tabs;
        let curTab = null;
        for (let index = 0, len = tabs.length; index < len; index++) {
          if (tabs[index].path === path) {
            curTab = tabs[index];
            curTab.index = index;
          }
        }
        return curTab;
      },
      /**
       * 根据路径获得对应的配置项
       * @param {Object} data 路径
       */
      setConfigMap(data) {
        for (let item of data) {
          let lists = item.lists;
          let isLeaf = lists ? lists.length === 0 : true;
          if (isLeaf) {
            this.configMap[item.path] = item;
          } else {
            this.setConfigMap(item.lists);
          }
        }
      },
      /**
       * 设置tabs栏目的添加或者跳转
       * @param {Object} route 当前的路由地址
       */
      setTabs(route) {
        let path = route.path;
        // 路径至匹配前三
        let pathArr = path.split("/");
        pathArr.length = 3;
        path = pathArr.join("/");



        let curConfig = this.hasTbasByPath(path);
        if (curConfig) {
          this.curPath = curConfig.path;
        } else {
          this.curPath = path;
          curConfig = this.configMap[path];
          if (!curConfig) {
            curConfig = {
              'title': '404页面',
              'path': path
            };
          }
          this.tabs.push(curConfig);
          this.addAddkeepLiveInclude(route.name);

          this.$nextTick(() => {
            let outW = this.$refs.outMyTabs.offsetWidth;
            let scrollW = this.$refs.scrollTabs.offsetWidth;
            let fool = Math.floor(scrollW / outW);

            if (fool > this.prevIndex) {
              this.$refs.scrollTabs.style.left = -fool * outW + "px";
              this.prevIndex = fool;
            }

            if (this.$refs.scrollTabs.offsetWidth >= this.$refs.outMyTabs.offsetWidth) {
              this.setOverFlowTabs(true);
            } else {
              this.setOverFlowTabs(false);
            }
          })

        }
      },
      /**
       *  弹窗上面的选项按钮点击后触发
       * @param {Number} index 点击了第几个
       * @param {Object} item 点击了这个项的信息
       */
      promptClick(index, item) {
        this.isShowPromptBox = false;
        switch (item.id) {
          case 0:// 关闭当前
            this.delClick(this.curElItem, this.curElIndex);
            break;
          case 1:// 关闭其他
            this.tabs = this.tabs.splice(this.curElIndex, 1);
            this.resetAddKeepLiveInclude(this.keepLiveInclude.splice(this.curElIndex, 1));
            this.curPath = this.curElItem.path;
            this.makeMove();
            break;
          case 2:// 关闭全部
            this.tabs = [];
            this.resetAddKeepLiveInclude([]);
            this.$router.push({path: this.fristPath});
            if (this.curElItem.path === this.fristPath) {
              this.setTabs(this.$route);
            }
            this.makeMove();
            break;
        }
      },
      /**
       * 拦截右键，并关闭菜单
       * @param {Object} event event
       */
      contextmenuClose(event) {
        // 鼠标右键拦截
        event.preventDefault ? event.preventDefault() : (event.returnValue = false);
        this.isShowPromptBox = false;
      },
      /**
       * 拦截右键，并弹出菜单
       * @param {Object} event event
       * @param {Object} item item项的数据
       * @param {Number} index 索引
       */
      contextmenu(event, item, index) {
        this.curElItem = item;
        this.curElIndex = index;
        let outW = this.$refs.outMyTabs.offsetWidth;
        // 鼠标右键拦截
        event.preventDefault ? event.preventDefault() : (event.returnValue = false);
        console.log('右键', item, index);
        this.isShowPromptBox = true;
        this.promptStyle.left = (event.layerX - this.prevIndex * outW) + 'px';
        this.promptStyle.top = event.layerY + 'px';
      },
      prev() {
        let outW = this.$refs.outMyTabs.offsetWidth; // 300 不变的
        this.prevIndex -= 1;
        if (this.prevIndex <= 0) {
          this.prevIndex = 0;
        }
        this.$refs.scrollTabs.style.left = -this.prevIndex * outW + "px";
      },
      next() {
        let outW = this.$refs.outMyTabs.offsetWidth; // 300 不变的
        let scrollW = this.$refs.scrollTabs.offsetWidth; // 增加就越长
        let fool = Math.floor(scrollW / outW);
        this.prevIndex += 1;
        if (this.prevIndex >= fool) {
          this.prevIndex = fool;
        }
        this.$refs.scrollTabs.style.left = -this.prevIndex * outW + "px";
      },
      makeMove() {
        this.$nextTick(() => {
          let outW = this.$refs.outMyTabs.offsetWidth;
          let scrollW = this.$refs.scrollTabs.offsetWidth;
          let fool = Math.floor(scrollW / outW);

          if (fool < this.prevIndex) {
            this.$refs.scrollTabs.style.left = -fool * outW + "px";
            this.prevIndex = fool;
          }

          if (scrollW >= outW) {
            this.setOverFlowTabs(true);
          } else {
            this.setOverFlowTabs(false);
          }
        })
      }
    },
    computed: {
      ...mapGetters(['keepLiveInclude', 'getIsOverFlowTabs','getTabs'])
    },
    watch: {
      $route(newV) {
        this.setTabs(newV);
      },
      getTabs(newV) {
        this.setConfigMap(newV);
        this.setTabs(this.$route);
      }
    },
    mounted() {
      
    },
    destroyed() {
    }
  };
</script>
<style scoped lang="less">
  .hide {
    width: 0.2rem;
    height: 0.4rem;
    line-height: 0.4rem;
    text-align: center;
    z-index: 10;
    background-color: #fff;
    cursor: pointer;
    box-sizing: border-box;
    color: #909399;
    font-size: 0.16rem;
    box-shadow: 1px 1px 5px #303133;
  }

  .my-tabs {
    position: relative;

    .out-my-tabs {
      height: 0.5rem;
      width: 100%;
      /*flex: 1;*/
      overflow: hidden;
      position: relative;
      animation: myfirst;

      .tab-box {
        position: absolute;
        left: 0;
        top: 0;
        height: 0.5rem;
        transition: left 1s;
        -moz-transition: left 1s; /* Firefox 4 */
        -webkit-transition: left 1s; /* Safari and Chrome */
        -o-transition: left 1s; /* Opera */
        white-space: nowrap;
        display: inline-block;


        .tabs {
          height: 0.5rem;
          display: flex;
          /*display: -webkit-box;*/
          align-items: center;
          margin-block-start: 0;
          margin-block-end: 0;
          margin-inline-start: 0;
          margin-inline-end: 0;
          padding-inline-start: 0;
          box-sizing: border-box;
          border-bottom: 0.01rem solid #e6e6e6;

          > li {
            cursor: pointer;
            display: flex;
            align-items: center;
            margin: 0 0.05rem;
            padding: 0.05rem 0.08rem;
            border: 0.01rem solid #e6e6e6;
            font-size: 0.14rem;
            color: rgb(109, 114, 132);

            &.active {
              background-color: #ff9600;
              border-color: #ff9600;
              color: #fff;

              &::before {
                content: "";
                width: 0.08rem;
                height: 0.08rem;
                margin: 0 0.08rem 0 0;
                border-radius: 50%;
                background-color: #fff;
                display: inline-block;
              }

              i {
                color: #fff;
                opacity: 0.7;
              }

            }

            .del {
              margin-left: 0.1rem;
              font-size: 0.14rem;
              color: #2d3a4b;
              opacity: 0.5;

              &:hover {
                color: #a00;
              }
            }
          }
        }
      }
    }

    .prev:extend(.hide) {
      position: absolute;
      left: -5px;
      top: 0.05rem;

    }

    .next:extend(.hide) {
      position: absolute;
      right: -5px;
      top: 0.05rem;

    }

    .prompt-box {
      .mask {
        position: fixed;
        left: 0;
        top: 0;
        width: 100%;
        height: 100%;
      }

      .prompt {
        z-index: 1000;
        position: absolute;
        left: 0;
        top: 0;
        padding: 0.1rem 0;
        max-width: 2rem;
        border: 1px solid #eeeeee;
        background-color: #fff;
        border-radius: 0.05rem;

        > li {
          padding: 0.05rem 0.2rem;

          &:hover {
            background-color: #2d3a4b;
            color: #fff;
            cursor: pointer;
          }
        }
      }
    }
  }
</style>
